#include <stdio.h>
#include <stdlib.h>
#include "kernel_list.h"

typedef struct
{
    int data;
    struct list_head list; //定义的小结构体
} listNode;

// 创建链表节点
listNode *create_list_node(int data)
{
    listNode *n = malloc(sizeof(listNode));
    n->data = data;
    INIT_LIST_HEAD(&n->list);//初始化小结构体
    return n;
}

// 基于内核链表实现栈
typedef struct
{
    listNode *top; // 将头节点作为栈顶
    int size;  // 栈的长度
} LinkedListStack;

// 初始化栈
LinkedListStack *new_linked_list_stack()
{
    LinkedListStack *s = malloc(sizeof(LinkedListStack));
    s->top = create_list_node(-1);
    s->size = 0;

    return s;
}
/* 析构函数 */
void del_linked_list_stack(LinkedListStack *s)
{
    listNode *p, *n;
    // 遍历大结构体
    list_for_each_entry_safe(p, n, &s->top->list, list)
    {
        printf("%d \n", p->data);
        list_del(&p->list);
        free(p);
    }
    free(s->top);
    free(s);
}
/* 获取栈的长度 */
int size(LinkedListStack *s)
{
    return s->size;
}
/* 判断栈是否为空 */
int isEmpty(LinkedListStack *s)
{
    return size(s) == 0;
}
// 入栈
void push(LinkedListStack *s, int data)
{
    listNode *n = create_list_node(data);

    //头插法
    list_add(&n->list, &s->top->list); // 传入新节点和头节点

    // 更新栈成员数量(栈的长度)
    s->size++;
}
// 访问栈顶元素
int peek(LinkedListStack *s)
{
    if (s->size == 0)
    {
        printf("栈为空 \n");
        return -1;
    }
    // 小结构体转大结构体
    listNode *head = list_entry(s->top->list.next, listNode, list); // 传入头节点的地址，大结构体的名字，小结构体的名字

    return head->data;
}
// 出栈
int pop(LinkedListStack *s)
{
    if (isEmpty(s))
    {
        return 0;
    }

    int data = peek(s);//拿到栈顶元素

    struct list_head *head = s->top->list.next;

    listNode *h = list_entry(head, listNode, list);
    list_del(head); // 删除小结构体

    free(h); // 释放大结构体

    s->size--;

    return data;
}
int main(int argc, char const *argv[])
{

    LinkedListStack *s = new_linked_list_stack();

    push(s, 7);
    push(s, 8);
    push(s, 9);
    push(s, 10);
    push(s, 11);

    printf("栈顶 %d \n", peek(s));

    printf("栈顶 %d \n", pop(s));
    printf("栈顶 %d \n", pop(s));
    printf("栈顶 %d \n", pop(s));
    printf("栈顶 %d \n", pop(s));
    printf("栈顶 %d \n", pop(s));

    // del_linked_list_stack(s);

    return 0;
}
